home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-27 | 6.0 KB | 205 lines | [TEXT/CCL2] |
- ;;; File: parser/typedecl-parser Author: John
-
- (define (parse-type-decl interface?)
- (save-parser-context
- (let* ((sig (parse-signature))
- (contexts (signature-context sig))
- (simple (signature-type sig))
- (deriving '())
- (constrs '()))
- ;; #t = builtins ([] (,,) ->) not allowed
- (check-simple simple '#t "type declaration")
- (let ((annotations (parse-constr-annotations)))
- (token-case
- (= (setf constrs (parse-constrs))
- (token-case
- (|deriving|
- (setf deriving
- (token-case
- (\(
- (token-case
- (\) '())
- (else (parse-class-list))))
- (tycon (list (class->ast)))
- (else (signal-invalid-syntax "a deriving clause")))))))
- (else
- (when (not interface?)
- (signal-missing-constructors))))
- (make data-decl (context contexts) (simple simple)
- (constrs constrs) (deriving deriving)
- (annotations annotations))))))
-
- (define (signal-missing-constructors)
- (parser-error 'missing-constructors
- "Data type definition requires constructors"))
-
- (define (check-simple simple fresh? where)
- (when (not (tycon? simple))
- (signal-not-simple where))
- (when (and fresh? (not (eq? (tycon-def simple) *undefined-def*)))
- (signal-not-simple where))
- (let ((tyvars (map (lambda (arg)
- (when (not (tyvar? arg))
- (signal-not-simple where))
- (tyvar-name arg))
- (tycon-args simple))))
- (when (not (null? (find-duplicates tyvars)))
- (signal-unique-tyvars-required))))
-
- (define (signal-unique-tyvars-required)
- (parser-error 'unique-tyvars-required
- "Duplicate type variables appear in simple."))
-
- (define (signal-not-simple where)
- (parser-error 'not-simple "Simple type required in ~a." where))
-
- (define (parse-constrs)
- (let ((constr (parse-constr)))
- (token-case
- (\| (cons constr (parse-constrs)))
- (else (list constr)))))
-
- (define (parse-constr)
- (save-parser-context
- (let ((saved-excursion (save-scanner-state)))
- (token-case
- (consym/paren
- (parse-prefix-constr))
- (else
- (let ((type1 (parse-btype))
- (anns (parse-constr-annotations)))
- (token-case
- (conop
- (parse-infix-constr (tuple type1 anns)))
- (else
- (restore-excursion saved-excursion)
- (parse-prefix-constr)))))))))
-
- (define (parse-prefix-constr)
- (token-case
- (con
- (let* ((con (con->ast))
- (types (parse-constr-type-list)))
- (make constr (constructor con) (types types))))
- (else
- (signal-missing-token "<con>" "constrs list"))))
-
- (define (parse-constr-type-list)
- (token-case
- (atype-start
- (let* ((atype (parse-atype))
- (anns (parse-constr-annotations)))
- (cons (tuple atype anns)
- (parse-constr-type-list))))
- (else '())))
-
- (define (parse-infix-constr t+a1)
- (let* ((con (conop->ast))
- (type2 (parse-btype))
- (anns (parse-constr-annotations)))
- (make constr (constructor con) (types (list t+a1 (tuple type2 anns))))))
-
- (define (parse-class-list)
- (token-case
- (tycon (let ((class (class->ast)))
- (token-case
- (\, (cons class (parse-class-list)))
- (\) (list class))
- (else (signal-missing-token "`)' or `,'" "deriving clause")))))
- (else (signal-missing-token "<tycon>" "deriving clause"))))
-
- (define (parse-constr-annotations)
- (token-case
- ((begin-annotation no-advance)
- (let ((annotations (parse-annotations 'constructor)))
- (append annotations (parse-constr-annotations))))
- (else '())))
-
- (define (parse-synonym-decl)
- (save-parser-context
- (let* ((sig (parse-signature))
- (contexts (signature-context sig))
- (simple (signature-type sig)))
- (check-simple simple '#t "type synonym declaration")
- (when (not (null? contexts))
- (signal-no-context-in-synonym))
- (require-token = (signal-missing-token "`='" "type synonym declaration"))
- (let ((body (parse-type)))
- (make synonym-decl (simple simple) (body body))))))
-
- (define (signal-no-context-in-synonym)
- (parser-error 'no-context-in-synonym
- "Context is not permitted in type synonym declaration."))
-
- (define (parse-class-decl)
- (save-parser-context
- (let ((supers (parse-optional-context)))
- (token-case
- (tycon
- (let ((class (class->ast)))
- (token-case
- (tyvar
- (let* ((class-var (token->symbol))
- (decls (parse-where-decls)))
- (make class-decl (class class) (super-classes supers)
- (class-var class-var) (decls decls))))
- (else
- (signal-missing-token "<tyvar>" "class declaration")))))
- (else (signal-missing-token "<tycon>" "class declaration"))))))
-
- (define (parse-instance-decl interface? deriving?)
- (save-parser-context
- (let ((contexts (parse-optional-context))
- (decls '()))
- (token-case
- (tycon
- (let* ((class (class->ast))
- (simple (parse-type)))
- (when (not interface?)
- (setf decls (parse-where-decls)))
- (if deriving?
- (unless (tyvar? simple)
- (signal-missing-token "<tyvar>"
- "instance within deriving declaration"))
- (check-simple simple '#f "instance declaration"))
- (make instance-decl (context contexts) (class class)
- (simple simple) (decls decls))))
- (else (signal-missing-token "<tycon>" "instance declaration"))))))
-
-
- ;;; This is a Yale extension for derived instances
-
- ;;; deriving [Context =>] D a where
- ;;; instance i1
- ;;; instance i2 ...
-
- (define (parse-deriving-decl)
- (save-parser-context
- (let* ((sig (parse-signature))
- (contexts (signature-context sig))
- (simple (signature-type sig))
- (inst-decls '()))
- (check-simple simple '#t "deriving declaration")
- (token-case
- (|where|
- (setf inst-decls (parse-instance-decl-list)))
- (else (signal-missing-token "where" "deriving declaration")))
- (make deriving-decl (constraints contexts) (simple simple)
- (inst-decls inst-decls)))))
-
- (define (parse-instance-decl-list)
- (start-layout (function parse-instance-list-1)))
-
- (define (parse-instance-list-1 in-layout?)
- (token-case
- (|instance|
- (let ((idecl (parse-instance-decl '#f '#t)))
- (token-case
- (\; (cons idecl (parse-instance-list-1 in-layout?)))
- (else (close-layout in-layout?)
- (list idecl)))))
- (else
- (close-layout in-layout?)
- '())))
-
-